#include <netlib/net/socket.h>
#include <netlib/packet/messagequeue.h>
#include <netlib/packet/packet.h>

using namespace netlib::packet;

MessageQueue::MessageQueue()
{
}

MessageQueue::~MessageQueue()
{
}

bool MessageQueue::pop( netlib::packet::MessageQueue::MessageInfo *messageInfo )
{
	netlib::packet::MessageQueue::MessageInfo *info = m_messageList.pop();
	if  ( !info ) return ( false );

	messageInfo->messageID = info->messageID;
	messageInfo->lparam = info->lparam;
	messageInfo->wparam = info->wparam;

	m_messagInfoPool.push( info );

	return ( true );
}

void MessageQueue::push( UINT messageID, WPARAM wparam, LPARAM lparam  )
{
	netlib::packet::MessageQueue::MessageInfo *info = m_messagInfoPool.pop();
	info->messageID = messageID;
	info->lparam = lparam;
	info->wparam = wparam;

	if ( info->messageID == WM_SOCKET_RECEIVE )
	{
		if ( m_idleMessageIDList.find( ( ( netlib::packet::Packet *)wparam )->ID() ) != m_idleMessageIDList.end() )
		{
			m_idleMessageList.push( info );
			return;
		}
	}
	m_messageList.push( info );
		
}	

void MessageQueue::addIdleMessageID( UINT messageID )
{
	m_idleMessageIDList.insert( messageID );
}

bool MessageQueue::popIdle( netlib::packet::MessageQueue::MessageInfo *messageInfo )
{
	netlib::packet::MessageQueue::MessageInfo *info = m_idleMessageList.pop();
	if  ( !info ) return ( false );

	messageInfo->messageID = info->messageID;
	messageInfo->lparam = info->lparam;
	messageInfo->wparam = info->wparam;

	m_messagInfoPool.push( info );

	return ( true );
}


void MessageQueue::remove( LPARAM lparam )
{
	for ( ;; )
	{
		netlib::packet::MessageQueue::MessageInfo *info = 
			m_idleMessageList.findErase( bind2nd( FindMessageInfoByLPARAM(), lparam ) );
		if ( !info ) break;
		
		m_messagInfoPool.push( info );
	}
	for ( ;; )
	{
		netlib::packet::MessageQueue::MessageInfo *info = 
			m_messageList.findErase( bind2nd( FindMessageInfoByLPARAM(), lparam ) );
		if ( !info ) break;
		
		m_messagInfoPool.push( info );
	}
}